home *** CD-ROM | disk | FTP | other *** search
- Path: info.ucla.edu!agate!kaskel
- From: kaskel@kirkuk.berkeley.edu (Bruce Kaskel)
- Newsgroups: sci.math,comp.programming,comp.lang.c
- Subject: Re: Tough FACTORIAL math problem...
- Date: 19 Feb 1996 11:00:05 GMT
- Organization: U.C. Berkeley Math. Department.
- Message-ID: <4g9l7l$9br@agate.berkeley.edu>
- References: <DMy5wC.HoL@cwi.nl> <mjs.824400445@hubcap> <4g48sg$ljq@agate.berkeley.edu> <1996Feb19.051528.14105@news.etc.bc.ca>
- NNTP-Posting-Host: kirkuk.berkeley.edu
-
- In article <1996Feb19.051528.14105@news.etc.bc.ca>,
- Robert Morewood <rmorewoo@cln.etc.bc.ca> wrote:
- >
- >The problem was to find the last non-zero digit of a large factorial.
- >(For example 1000!)
- [snip]
- >I solved did the 1000! problem quite easily on paper using a recursive
- >approach based on the observation that:
- >{ Product mod 10 of odd numbers not divisible by 5 less than or equal to N
- >{ depends only on N MOD 20. (Since 1*3*7*9*11*13*17*19 = 1 Mod 10.)
-
- Very nice! Here is a C-implemenation of your recursive algorithm.
-
- I figure it should be about 100 times faster for 1000! than the looping
- methods.
-
- --Bruce
- ============================================================================
-
- int a[20]={1,1,1,3,3,3,3,1,1,9,9,9,9,7,7,7,7,9,9,1};
- int b[4]={6,2,4,8};
-
- int rightmost_nonzero_digit(n)
- int n;
- {
- int u,t;
- if(n<2) return(1);
- foo(n,&u,&t);return((u*b[t])%10);
- }
-
- int foo(n,x,y)
- int n,*x,*y;
- {
- int i=1,j=0,m=n>>1,u,f;
- odds(n,&u,&f);
- if (m>1) foo(m,&i,&j);
- *x=(u*i)%10;*y=(m+(4-f)+j)&3;
- }
-
- int odds(n,x,f)
- int n,*x,*f;
- {
- int q=1,r=0,s=n/5;
- if(s>2) odds(s,&q,&r);
- *x=(q*a[n%20])%10;
- *f=(r+((s+1)>>1))&3;
- return;
- }
-
-
-
-